package com.xhtt.fzxy.console;

import com.xhtt.fzxy.console.db.AdminDBUtil;

import net.lastcoder.ifserver.util.StringUtils;

import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpSession;

/**
 * auth: WenYF
 * date: 2018/5/5
 */
public class AdminManager {
    private static class InstanceHolder {
        private static AdminManager instance = new AdminManager();
    }
    
    public static AdminManager getInstance() {
        return InstanceHolder.instance;
    }

    private AdminsWrapper admins;

    public AdminManager() {
        this.admins = new AdminsWrapper();
    }

    public Admin getAdmin(ServletRequest req, ServletResponse res, HttpSession httpSession) {
        String sessionId = httpSession.getId();
        Admin admin = admins.get(sessionId);

        if (admin == null) {
            return null;
        }

        if (System.currentTimeMillis() > admin.expire + admin.startTime) {
            admins.remove(admin.sessionId);
            return null;
        }

        return admin;
    }

    /**
     * 如果返回null， 表示登录失败
     *
     * @param sessionId
     * @param email
     * @param password
     * @param ip
     * @return
     */
    public Admin login(String sessionId, String email, String password, String ip) {
        JSONObject success = AdminDBUtil.login(email, password, ip);
        if (success == null) {
            return null;
        }
        
        return createAdmin(success.getString("username"), sessionId, email, success.getString("name")
                , success.optInt("level", Admin.Level.other)
                , StringUtils.randomString(16), success.getLong("lastTimeLogin"));
    }

    private Admin createAdmin(String username, String sessionId, String email, String name, int level, String auth, long lastTime) {
        Admin admin = new Admin();
        admins.put(sessionId, admin);
        admin.email = email;
        admin.name = name;
        admin.authToken = auth;
        admin.startTime = System.currentTimeMillis();
        admin.lastTimeLogin = lastTime;
        admin.currentLoginTime = System.currentTimeMillis();
        admin.expire = 60 * 60 * 1000;
        admin.level = level;
        String levelName = "其他人员";
        switch (level) {
            case 0:
                levelName = "超级管理员";
                break;
            case 1:
                levelName = "管理员";
                break;
            case 2:
                levelName = "运行";
                break;
            case 3:
                levelName = "客服";
                break;
            case 4:
                levelName = "其他人员";
                break;
        }
        admin.levelName = levelName;
        admin.username = username;
        admin.sessionId = sessionId;
        return admin;
    }
    
    
    private static class AdminsWrapper {
        Map<String, Admin> sessionMap;
        Map<String, Admin> usernameMap;
        
        public AdminsWrapper() {
            usernameMap = new HashMap<>();
            sessionMap = new HashMap<>();
        }
        
        public Admin get(String sessionId) {
            return sessionMap.get(sessionId);
        }
        
        public Admin remove(String sessionId) {
            Admin admin = sessionMap.remove(sessionId);
            if (admin != null) {
                usernameMap.remove(admin.username);
            }
            
            return admin;
        }
        
        public void put(String sessionId, Admin admin) {
            // 先判断是否有登录
            if (usernameMap.containsKey(admin.username)) {
                // 表示连个浏览器在登录，或者之前的cookie被清理了
                // TODO
            }
            // 那么这里要移除之前的
            Admin removeAdmin = usernameMap.remove(admin.username);
            if (removeAdmin != null) {
                sessionMap.remove(removeAdmin.sessionId);
            }
                    
            usernameMap.put(admin.username, admin);
            sessionMap.put(sessionId, admin);
        }
    }
}
